﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PrearrangedChaos.AgileZen.Service;
using PrearrangedChaos.AgileZen.Service.Model;

namespace prearrangedchaos.tfszen.integrationtests
{
    [TestClass]
    public class ZenServiceTest
    {
        private const int ProjectId = 21738; //54179; 
        const int StoryId = 1;

        [TestMethod]
        public void ZenService_GetStory_WithMetrics_Test()
        {

            ZenService service = new ZenService();

            IStory story = service.GetStory(ProjectId, StoryId, options => options.WithMetrics().WithDetails().WithTags());

            int id = story.Id;

            foreach (var tag in story.Tags)
            {
                var y = tag.Name;
            }
        }

        [TestMethod]
        public void ZenService_GetAttachments_Test()
        {
            ZenService service = new ZenService();
            IEnumerable<IAttachment> attachments = service.GetAttachments(ProjectId, 1);

            var x = attachments.ToArray();
            var y = x.Length;
        }

        [TestMethod]
        public void ZenService_GetComments_Test()
        {
            ZenService service = new ZenService();
            IEnumerable<IComment> comments = service.GetComments(ProjectId, 1);

            var x = comments.ToArray();
            var y = x.Length;
        }

        [TestMethod]
        public void ZenService_GetInvites_Test()
        {
            ZenService service = new ZenService();
            IEnumerable<IInvite> invites = service.GetInvites(ProjectId);

            var x = invites.ToArray();
            var y = x.Length;
        }


        [TestMethod]
        public void ZenService_GetPhases_Test()
        {
            ZenService service = new ZenService();
            IEnumerable<IPhase> phases = service.GetPhases(ProjectId);

            var x = phases.ToArray();
            var y = x.Length;
        }

        [TestMethod]
        public void ZenService_GetProjects_Test()
        {
            ZenService service = new ZenService();
            IEnumerable<IProject> projects = service.GetProjects()
                .WithMembers
                .WithMetrics
                .Filter(project => project.Owner.Is("Martin Larsen"));

            var x = projects.ToArray();
            var y = x.Length;
        }

        [TestMethod]
        public void ZenService_GetTags_Test()
        {
            ZenService service = new ZenService();
            IEnumerable<ITag> tags = service.GetTags(ProjectId);

            var x = tags.ToArray();
            var y = x.Length;
        }

        [TestMethod]
        public void ZenService_GetTasks_Test()
        {
            ZenService service = new ZenService();
            IEnumerable<ITask> tasks = service.GetTasks(ProjectId, 1);

            var x = tasks.ToArray();
            var y = x.Length;
        }

        [TestMethod]
        public void ZenService_GetRoles_Test()
        {
            ZenService service = new ZenService();
            IEnumerable<IRole> roles = service.GetRoles(ProjectId)
                .Filter(role => role.Name.Is("Administrators"));

            var x = roles.ToArray();
            var y = x.Length;
        }

        [TestMethod]
        public void ZenService_GetStories_Test()
        {
            int projectId = 21738;

            ZenService service = new ZenService();
            service.PageSize = 50;

            IEnumerable<IStory> stories = service.GetStories(projectId)
                .WithTags
                .WithTasks
                .WithDetails
                .Filter(story =>
                       (story.Color.Blue & story.Tag.Is("Bug")) |
                       story.Tag.Is("CriticalBug"));


            var x = stories.ToArray();
            var y = x.Length;
        }

        [TestMethod]
        public void ZenService_GetMe_Test()
        {
            ZenService service = new ZenService();
            IUser user = service.GetMe();
            int userId = user.Id;
        }

        [TestMethod]
        public void ZenService_CreateStory_Test()
        {
            ZenService service = new ZenService();
            IStory story = service.CreateStory(
                ProjectId,
                "Test story from API 13",
                deadline: DateTime.UtcNow,
                color: StoryColor.Red,
                ownerId: service.GetMe().Id,
                phaseId: service.GetPhases(ProjectId).First(p => p.Name == "Backlog").Id,
                tags: new[] {new Tag() {Id = 270577}, new Tag() {Id = 270578}});
                //tags: new [] { service.CreateTag(ProjectId, "tag1"), service.CreateTag(ProjectId, "tag2") });

            StoryStatus status = story.Status;
        }

        [TestMethod]
        public void ZenService_CreateRole_Test()
        {
            ZenService service = new ZenService();
            IRole role = service.CreateRole(
                ProjectId,
                "Some Role",
                ApiAccess.Read);

            int roleId = role.Id;
        }

        [TestMethod]
        public void ZenService_CreateTask_Test()
        {
            ZenService service = new ZenService();
            ITask task = service.CreateTask(
                ProjectId,
                StoryId,
                "Some Task",
                TaskStatus.Complete);

            int id = task.Id;
        }

        [TestMethod]
        public void ZenService_CreateUpdateStory_Test()
        {
            ZenService service = new ZenService();
            IStory story = service.CreateStory(
                ProjectId,
                "Test story from API 14",
                deadline: DateTime.UtcNow,
                color: StoryColor.Red,
                ownerId: service.GetMe().Id,
                phaseId: service.GetPhases(ProjectId).First(p => p.Name == "Backlog").Id);

            story.Size = "Large";

            service.UpdateStory(story as IStoryUpdater, ProjectId);

            ITag tag = service.CreateTag(ProjectId, "ChangeSet:4575");

            service.AddTagToStory(ProjectId, story.Id, tag.Id);

            StoryStatus status = story.Status;
        }

        [TestMethod]
        public void ZenService_UpdateStoryDetails_Test()
        {
            ZenService service = new ZenService();

            IStoryUpdater story = service.GetStory(ProjectId, 1);
            story.Details = "Some details 3";
            story.Status = StoryStatus.Blocked;
            story.BlockedReason = "xxx";

            service.UpdateStory(story, ProjectId);
        }

        [TestMethod]
        public void ZenService_GetTag_Test()
        {
            ZenService service = new ZenService();
            IStory story = service.CreateStory(
                ProjectId,
                "Tag story",
                deadline: DateTime.UtcNow,
                color: StoryColor.Red,
                ownerId: service.GetMe().Id,
                phaseId: service.GetPhases(ProjectId).First(p => p.Name == "Backlog").Id);

            var label = "tag test:" + DateTime.Now;

            ITag tag = service.CreateTag(ProjectId, label);
            service.AddTagToStory(ProjectId, story.Id, tag.Id);

            Assert.IsNotNull(service.GetTag(ProjectId, label));
            Assert.IsNotNull(service.GetTag(ProjectId, tag.Id));

        }

        [TestMethod]
        public void ZenService_UpdateTag_Test()
        {
            ZenService service = new ZenService();
            IStory story = service.CreateStory(
                ProjectId,
                "Tag story",
                deadline: DateTime.UtcNow,
                color: StoryColor.Red,
                ownerId: service.GetMe().Id,
                phaseId: service.GetPhases(ProjectId).First(p => p.Name == "Backlog").Id);

            var label = "tag test:" + DateTime.Now;

            ITag tag = service.CreateTag(ProjectId, label);
            service.AddTagToStory(ProjectId, story.Id, tag.Id);
            tag.Name = "changed";
            service.UpdateTag(tag, ProjectId);
            Assert.AreEqual("changed", service.GetTag(ProjectId, tag.Id).Name);

        }

        [TestMethod]
        public void ZenService_RemoveTagFromStory_Test()
        {
            ZenService service = new ZenService();
            IStory story = service.CreateStory(
                ProjectId,
                "Tag story",
                deadline: DateTime.UtcNow,
                color: StoryColor.Red,
                ownerId: service.GetMe().Id,
                phaseId: service.GetPhases(ProjectId).First(p => p.Name == "Backlog").Id);

            var label = "tag test:" + DateTime.Now;

            ITag tag = service.CreateTag(ProjectId, label);
            var id = tag.Id;
            service.AddTagToStory(ProjectId, story.Id, tag.Id);
            service.RemoveTagFromStory(ProjectId, story.Id, tag.Id);
 
        }

        [TestMethod]
        public void ZenService_DeleteTag_Test()
        {
            ZenService service = new ZenService();
            var label = "tag test:" + DateTime.Now;
            ITag tag = service.CreateTag(ProjectId, label);
            service.DeleteTag(ProjectId, tag.Id);
        }


        private class StoryUpdaterMock : IStoryUpdater
        {
            public int Id { get; set; }
            public StoryColor? Color { get; set; }
            public DateTime? Deadline { get; set; }
            public IUser Owner { get; set; }
            public IPhase Phase { get; set; }
            public string Priority { get; set; }
            public string Size { get; set; }
            public StoryStatus? Status { get; set; }
            public string Text { get; set; }
            public string Details { get; set; }
            public string BlockedReason { get; set; }
        }
    }
}
